# -*- coding: utf-8 -*-

from common import *
from settings import logger
import re
import akshare as ak
from pandas.core.frame import DataFrame
import json

columns = ["名称", "代码", "最新价", "涨跌幅", "换手率", "涨速", "流通市值", "行业", "主力资金"]



def update_get_dp():
    """
    获取大盘综合信息
    """
    if check_time() is False:
        return
    logger.info("更新大盘数据")
    now = datetime.now()
    # while not is_workday(now):
    #     now = now - timedelta(days=1)
    date_num = convert_to_num(now)
    zs, zdf = get_zs()

    stock_market_activity_legu_df = ak.stock_market_activity_legu()
    ap = stock_market_activity_legu_df["value"][10].strip()

    stock_a_congestion_lg_df = ak.stock_a_congestion_lg()
    crowding_degree = float(stock_a_congestion_lg_df["congestion"].values[-1]) * 100

    sgt_df = ak.stock_hsgt_north_net_flow_in_em(symbol="深股通")

    hgt_df = ak.stock_hsgt_north_net_flow_in_em(symbol="沪股通")

    bx_df = ak.stock_hsgt_north_net_flow_in_em(symbol="北上")
    stock_zt_pool_dtgc_em_df = ak.stock_zt_pool_dtgc_em(date=date_num)
    stock_zt_pool_em_df = ak.stock_zt_pool_em(date=date_num)  # 涨停
    if not sgt_df.empty:
        # 不为空更新
        hgt_lr = hgt_df["value"].values[-1]
        sgt_lr = sgt_df["value"].values[-1]
        bx_lr = bx_df["value"].values[-1]

    zt_num = len(stock_zt_pool_em_df)
    dt_num = len(stock_zt_pool_dtgc_em_df)
    # 指数
    data = {}
    data["exponent"] = zs
    # 指数涨跌幅
    data["dp_zdf"] = zdf
    data["zt_num"] = zt_num
    data["dt_num"] = dt_num
    data["AP"] = ap
    data["crowding_degree"] = crowding_degree
    data["sgt_lr"] = sgt_lr
    data["hgt_lr"] = hgt_lr
    data["bx_lr"] = bx_lr
    dp_info = json.dumps(data)
    r_con.set("dp_info", dp_info)

def get_filter_data(col = "涨速"):
        global_df_json = r_con.get("global_df")
        df_global = pd.read_json(global_df_json, dtype={"代码": 'str'})
        df_global.sort_values(by=col, axis=0, ascending=False, inplace=True)

        bk_data_set_json = r_con.get("bk_data_set")
        bk_data_set = json.loads(bk_data_set_json)

        def add_col_big_fund(row):
            """
            添加大资金列
            """
            return 0
        
    
        def add_hy_name(row):
            """
            添加行业
            """
            code = row["代码"]
            
            for tup in bk_data_set:
                if tup[0] == code:
                    return tup[1]
            return "行业未更新"
        df_global["行业"] = df_global.apply(add_hy_name, axis=1)

        df_global["主力资金"] = df_global.apply(add_col_big_fund, axis=1)
        
        df_global = df_global.loc[
            :, columns]
        return df_global


@decorated("更新大资金")
def update_dzj_data():
    """
    更新大资金
    """
    open_home()
    nwp_tab = open_task_page("大单净量")
    big_fund_df = get_task_data(nwp_tab)
    if big_fund_df is None:
        return
    if big_fund_df is None:
        return
    nwp_columns = big_fund_df.columns.tolist()
    nwp_col_name = ""
    for col in nwp_columns:
        if "外盘" in col and "内盘" in col:
            nwp_col_name = col
            break

    big_fund_df = big_fund_df.loc[
        :, ["dde大单净量", "股票代码", nwp_col_name]
    ]
    dzj_df_json = big_fund_df.to_json()
    r_con.set("dzj_df", dzj_df_json)

    bk_data_set_json = r_con.get("bk_data_set")
    bk_data_set = json.loads(bk_data_set_json)

    global_df_json = r_con.get("global_df")
    df = pd.read_json(global_df_json, dtype={"代码": 'str'})

    if not isinstance(big_fund_df, DataFrame):
        return
    
    code_list = big_fund_df["股票代码"].tolist()

    if not isinstance(df, DataFrame):
        return
    
    def add_col_big_fund(row):
        """
        添加大资金列
        """
        result = 0
        if not isinstance(big_fund_df, DataFrame):
            r_con.set("update_date", "大资金数据为空")
            return result
        name = "dde大单净量"
        big_fund_df[name] = big_fund_df[name].apply(lambda x: float(x))
        big_fund_list = big_fund_df[name].tolist()
        code_list = big_fund_df["股票代码"].tolist()
        code = row["代码"]
        if code in code_list:
            return big_fund_list[code_list.index(code)]
        return result
    
    
    def add_hy_name(row):
        """
        添加行业
        """
        code = row["代码"]
        
        for tup in bk_data_set:
            if tup[0] == code:
                return tup[1]
        return "行业未更新"
    
    def add_nwp(row):
        code = row["代码"]
        nwp_list = big_fund_df[nwp_col_name].tolist()
        if code in code_list:
            return nwp_list[code_list.index(code)]
        return 0

    df = df[df["代码"].isin(code_list)]
    dzj_df = df.copy(deep=True)
    dzj_df.set_index(["代码"])
    
    dzj_df["行业"] = dzj_df.apply(add_hy_name, axis=1)

    dzj_df["主力资金"] = dzj_df.apply(add_col_big_fund, axis=1)

    dzj_df = dzj_df.loc[
        :, columns
    ]
    dzj_df["内外盘比"] = dzj_df.apply(add_nwp, axis=1)
    dzj_df.fillna(0, inplace=True)
    dzj_df.sort_values(["涨跌幅", "内外盘比", "主力资金"], ascending=[False, False, False], inplace=True)
    dzj_df_json = dzj_df.to_json()
    r_con.set("dzj_data", dzj_df_json)

@decorated("更新板块前十")
def update_bk10_data():
        dzj_df_json = r_con.get("dzj_df")
        big_fund_df = pd.read_json(dzj_df_json, dtype={"股票代码": 'str'})
        df_global = get_filter_data(col="涨跌幅")
        bk_df_josn = r_con.get("bk_data")
        bk_list = json.loads(bk_df_josn)
        bk_list = bk_list[0:10]
        def filter_bk(row):
            try:
                stock_bk_list = json.loads(row["行业"])
                for bk in bk_list:
                    name = bk["板块名称"]
                    if name in stock_bk_list:
                        return True 
            except Exception as err:
                pass
            return False
    
        code_list = big_fund_df["股票代码"].tolist()
        def add_col_big_fund(row):
            """
            添加大资金列
            """
            result = 0
            if not isinstance(big_fund_df, DataFrame):
                r_con.set("update_date", "大资金数据为空")
                return result
            name = "dde大单净量"
            big_fund_df[name] = big_fund_df[name].apply(lambda x: float(x))
            big_fund_list = big_fund_df[name].tolist()
            
            code = row["代码"]
            if code in code_list:
                return big_fund_list[code_list.index(code)]
            return result
            
        nwp_columns = big_fund_df.columns.tolist()
        nwp_col_name = ""
        for col in nwp_columns:
            if "外盘" in col and "内盘" in col:
                nwp_col_name = col
                break
        def add_nwp(row):
            code = row["代码"]
            nwp_list = big_fund_df[nwp_col_name].tolist()
            if code in code_list:
                return nwp_list[code_list.index(code)]
            return 0

        def add_bk(row):
            try:
                stock_bk_list = json.loads(row["行业"])
                for bk in bk_list:
                    name = bk["板块名称"]
                    if name in stock_bk_list:
                        return name
            except Exception as err:
                pass
            return ""

        def add_bk_zdf(row):
            try:
                stock_bk_list = json.loads(row["行业"])
                for bk in bk_list:
                    name = bk["板块名称"]
                    zdf = bk["涨跌幅"]
                    if name in stock_bk_list:
                        return zdf
            except Exception as err:
                pass
            return ""

        df_global = df_global[df_global["流通市值"]<450]
        df_global = df_global[df_global["涨跌幅"]>2]
        df_global = df_global.sort_values("涨跌幅", ascending=False)

        df_global = df_global[df_global.apply(filter_bk,axis=1)]
        df_global = df_global.head(100)

        df_global["板块"] = df_global.apply(add_bk,axis=1)
        df_global["板块涨跌幅"] = df_global.apply(add_bk_zdf,axis=1)

        df_global["主力资金"] = df_global.apply(add_col_big_fund,axis=1)
        

        df_global = df_global.sort_values(["板块涨跌幅", "涨跌幅"], ascending=[False, False])
        df_global.drop(["板块涨跌幅", "板块"], inplace=True,axis=1)
        df_global = df_global.loc[:, columns]
        df_global["内外盘比"] = df_global.apply(add_nwp,axis=1)

        df_global.fillna(0, inplace=True)
        df_bk10_json = df_global.to_json()
        r_con.set("bk10_data", df_bk10_json)

@decorated("更新成交对比")
def update_cjdb_data():
    """
    更新成交对比
    """

    bk_data_set_json = r_con.get("bk_data_set")
    bk_data_set = json.loads(bk_data_set_json)

    dzj_df_json = r_con.get("dzj_df")
    big_fund_df = pd.read_json(dzj_df_json, dtype={"股票代码": 'str'})

    global_df_json = r_con.get("global_df")
    df = pd.read_json(global_df_json, dtype={"代码": 'str'})

    codes_json = r_con.get("cjdb_codes")
    if not codes_json:
        return
    cjdb_codes = json.loads(codes_json)

    new_cjdb_df = df[df["代码"].isin(cjdb_codes)]
    cjdb_df = new_cjdb_df.copy(deep=True)

    def add_col_big_fund(row):
        """
        添加大资金列
        """
        result = 0
        if not isinstance(big_fund_df, DataFrame):
            r_con.set("update_date", "大资金数据为空")
            return result
        name = "dde大单净量"
        big_fund_df[name] = big_fund_df[name].apply(lambda x: float(x))
        big_fund_list = big_fund_df[name].tolist()
        code_list = big_fund_df["股票代码"].tolist()
        code = row["代码"]
        if code in code_list:
            return big_fund_list[code_list.index(code)]
        return result
    

    
    def add_hy_name(row):
        """
        添加行业
        """
        code = row["代码"]
        for tup in bk_data_set:
            if tup[0] == code:
                return tup[1]
        return "行业未更新"

    cjdb_df["行业"] = cjdb_df.apply(add_hy_name, axis=1)
    cjdb_df["主力资金"] = cjdb_df.apply(add_col_big_fund, axis=1)
    cjdb_df = cjdb_df.loc[
        :, columns
    ]

    cjdb_df.fillna(0, inplace=True)
    cjdb_df_json = cjdb_df.to_json()
    r_con.set("cjdb_data", cjdb_df_json)

@decorated("更新问财")
def update_wc(wc_type):
    """
    更新问财
    :param wc_type:
    :return:
    """
    zx_data_set_json = r_con.get("zx_data_set")
    zx_data_set = json.loads(zx_data_set_json)

    bk_data_set_json = r_con.get("bk_data_set")
    bk_data_set = json.loads(bk_data_set_json)

    dzj_df_json = r_con.get("dzj_df")
    big_fund_df = pd.read_json(dzj_df_json, dtype={"股票代码": 'str'})

    global_df_json = r_con.get("global_df")
    df = pd.read_json(global_df_json, dtype={"代码": 'str'})

    wc_codes_json = r_con.get(f"wc{wc_type}_codes")
    if not wc_codes_json:
        return
    wc_codes = json.loads(wc_codes_json)
    wc_codes = [re.findall(r"\b\d{6}\b", code)[0] for code in wc_codes]

    new_wc_df = df[df["代码"].isin(wc_codes)]
    wc_df = new_wc_df.copy(deep=True)

    wc_df["名称"] = wc_df["名称"].apply(lambda x: str(x) + f"-{wc_type}")

    def add_col_big_fund(row):
        """
        添加大资金列
        """
        result = 0
        if not isinstance(big_fund_df, DataFrame):
            r_con.set("update_date", "大资金数据为空")
            return result
        name = "dde大单净量"
        big_fund_df[name] = big_fund_df[name].apply(lambda x: float(x))
        big_fund_list = big_fund_df[name].tolist()
        code_list = big_fund_df["股票代码"].tolist()
        code = row["代码"]
        if code in code_list:
            return big_fund_list[code_list.index(code)]
        return result
    

    def add_hy_name(row):
        """
        添加行业
        """
        code = row["代码"]
        for tup in bk_data_set:
            if tup[0] == code:
                return tup[1]
        return "行业未更新"

    wc_df["行业"] = wc_df.apply(add_hy_name, axis=1)
    wc_df["主力资金"] = wc_df.apply(add_col_big_fund, axis=1)
    wc_df = wc_df.loc[
        :, columns
    ]
    wc_df.sort_values(by="主力资金", axis=0, ascending=False, inplace=True)
    wc_df_json = wc_df.to_json()
    r_con.set(f"wc{wc_type}_data", wc_df_json)


@decorated("更新内外盘")
def update_nwp_data():
    open_home()
    nwp_tab = open_task_page("内外盘比")
    nwp_df = get_task_data(nwp_tab)
    if nwp_df is None:
        return
    nwp_codes = nwp_df["股票代码"].to_list()
    bk_data_set_json = r_con.get("bk_data_set")
    bk_data_set = json.loads(bk_data_set_json)

    global_df_json = r_con.get("global_df")
    global_df = pd.read_json(global_df_json, dtype={"代码": 'str'})
    global_df = global_df[global_df["代码"].isin(nwp_codes)]
    def add_hy_name(row):
        """
        添加行业
        """
        code = row["代码"]
        for tup in bk_data_set:
            if tup[0] == code:
                return tup[1]
        return "行业未更新"
    
    def add_col_big_fund(row):
        """
        添加主力资金
        """
        code = row["代码"]
        zj = 0
        big_fund_list = nwp_df["dde大单净量"].tolist()
        if code in nwp_codes:
            zj =  big_fund_list[nwp_codes.index(code)]
        return zj
    

    nwp_columns = nwp_df.columns.tolist()
    nwp_col_name = ""
    for col in nwp_columns:
        if "外盘" in col and "内盘" in col:
            nwp_col_name = col
            break
    
    def add_nwp(row):
        code = row["代码"]
        nwp_list = nwp_df[nwp_col_name].tolist()
        if code in nwp_codes:
            return nwp_list[nwp_codes.index(code)]
        return 0

        
    
    global_df["主力资金"] = global_df.apply(add_col_big_fund, axis=1)
    global_df["行业"] = global_df.apply(add_hy_name, axis=1)
    global_df = global_df.loc[
        :, columns
    ]
    global_df["内外盘比"] = global_df.apply(add_nwp, axis=1)
    nwp_df_json = global_df.to_json()
    r_con.set("nwp_df", nwp_df_json)

def update_bk_data():
    if check_time() is False:
        return
    # 更新板块信息
    # df_gn = ak.stock_board_concept_name_em()
    # df_gn = df_gn[~df_gn["板块名称"].str.contains("昨日")]
    # df_gn = df_gn[:200]
    # df_gn.drop(["排名"], axis=1, inplace=True)
    # df_gn.drop(["最新价"], axis=1, inplace=True)
    # df_gn.drop(["涨跌额"], axis=1, inplace=True)
    # df_gn.drop(["总市值"], axis=1, inplace=True)

    df_hy = ak.stock_board_industry_name_em()
    df_hy.drop(["排名"], axis=1, inplace=True)
    df_hy.drop(["最新价"], axis=1, inplace=True)
    df_hy.drop(["涨跌额"], axis=1, inplace=True)
    df_hy.drop(["总市值"], axis=1, inplace=True)

    # df_all = pd.concat([df_gn, df_hy])
    df_hy = df_hy[df_hy["涨跌幅"] >= 1]
    df_hy.drop_duplicates(subset=["板块名称"], keep="first", inplace=True)
    df_hy.sort_values(by="涨跌幅", axis=0, ascending=False, inplace=True)
    df_json = df_hy.to_json(orient='records')
    r_con.set("bk_data", df_json)
    return df_hy

@decorated("更新总数据")
def update_data():
    """
    更新总数据, 所有数据-进程处理
    """
    if check_time() is False:
        return
    logger.warning("开始更新总数据")
    df_all = ak.stock_zh_a_spot_em()
    df = df_all.copy(deep=True)
    if not isinstance(df, DataFrame):
        return
    df.set_index(["代码"])

    df["最新价"] = df["最新价"].apply(lambda x: "%.2f" % x)

    df["流通市值"] = df["流通市值"].apply(lambda x: str_of_num(x))
    df = df[~df["名称"].str.contains("ST")]
    df = df[~df["名称"].str.contains("退市")]
    df = df[df["代码"].str[:1] != "8"]
    df = df[df["代码"].str[:1] != "4"]
    df = df[df["代码"].str[:2] != "30"]
    df = df[df["代码"].str[:3] != "688"]
    
    df.drop(["量比"], axis=1, inplace=True)
    df.fillna(0, inplace=True)
    logger.warning("初始数据数量：{}".format(len(df)))
    global_df = df.to_json()
    r_con.set("global_df", global_df)
    return df


@decorated("更新大资金 自选合并数据")
def update_dzj_zx_merge_data():
    df_json = r_con.get("dzj_data")
    dzj_df = pd.read_json(df_json, dtype={"代码": 'str'})

    zx_df_json = r_con.get("zx_data")
    zx_df = pd.read_json(zx_df_json, dtype={"代码": 'str'})

    if isinstance(dzj_df, DataFrame) and isinstance(zx_df, DataFrame):
        dzj_zx_merge_df = pd.concat([dzj_df, zx_df], axis=0)
        dzj_zx_merge_df.sort_values(by="主力资金", axis=0, ascending=False, inplace=True)
        dzj_zx_merge_df.drop_duplicates(subset=["代码"], keep="first", inplace=True)
        dzj_zx_merge_df.set_index(["代码"])
        dzj_zx_merge_df.fillna(0, inplace=True)
        dzj_zx_merge_df_json = dzj_zx_merge_df.to_json(orient='records')
        r_con.set("dzj_zx_merge", dzj_zx_merge_df_json)



@decorated(name="更新自选")
def update_zx_data():
    """
    更新自选数据-进程处理
    """
    zx_data_set_json = r_con.get("zx_data_set")
    zx_data_set = json.loads(zx_data_set_json)

    bk_data_set_json = r_con.get("bk_data_set")
    bk_data_set = json.loads(bk_data_set_json)


    dzj_df_json = r_con.get("dzj_df")
    big_fund_df = pd.read_json(dzj_df_json, dtype={"股票代码": 'str'})
    
    global_df_json = r_con.get("global_df")
    df = pd.read_json(global_df_json, dtype={"代码": 'str'})

    code_list = [i[0] for i in zx_data_set]
    if not code_list:
        return
    if not isinstance(df, DataFrame):
        return
    c_zx_df = df[df["代码"].isin(code_list)]
    zx_df = c_zx_df.copy(deep=True)

    zx_df.set_index(["代码"])

    def add_col_big_fund(row):
        """
        添加大资金列
        """
        result = 0
        if not isinstance(big_fund_df, DataFrame):
            r_con.set("update_date", "大资金数据为空")
            return result
        name = "dde大单净量"
        big_fund_df[name] = big_fund_df[name].apply(lambda x: float(x))
        big_fund_list = big_fund_df[name].tolist()
        
        code_list = big_fund_df["股票代码"].tolist()
        code = row["代码"]
        if code in code_list:
            return big_fund_list[code_list.index(code)]
        return result

    
    def add_hy_name(row):
        """
        添加行业
        """
        code = row["代码"]
        for tup in bk_data_set:
            if tup[0] == code:
                return tup[1]
        return "行业未更新"
    
    
    zx_df["行业"] = zx_df.apply(add_hy_name, axis=1)
    zx_df["主力资金"] = zx_df.apply(add_col_big_fund, axis=1)
    
    zx_df.sort_values(by="主力资金", axis=0, ascending=True, inplace=True)
    zx_df = zx_df.loc[
        :, columns,
    ]
    zx_df.fillna(0, inplace=True)
    zx_data_json = zx_df.to_json()
    r_con.set("zx_data", zx_data_json)


def task_update_volume_ratio():
    """
    更新成交量
    """
    sqlite3_conn = sqlite3.connect("stock.db")
    cursor = sqlite3_conn.cursor()
    sql = "SELECT * FROM zxStock"
    cursor.execute(sql)
    data_all = cursor.fetchall()
    code_list = [i[0] for i in data_all]
    for code in code_list:
        volume_ratio, pre_volume = get_pre_volume(code)
        sql = f"update zxStock set volume_ratio='{volume_ratio}', pre_volume='{pre_volume}' where code='{code}'"
        sqlite3_conn.commit()
    sqlite3_conn.close()


def task_update_gn():
    """
    更新概念
    """
    sqlite3_conn = sqlite3.connect("stock.db")
    cursor = sqlite3_conn.cursor()
    df_gn = ak.stock_board_concept_name_em()
    df_hy = ak.stock_board_industry_name_em()
    df_all = pd.concat([df_hy, df_gn])
    df_all.drop_duplicates(subset=["板块名称"], keep="first", inplace=True)
    names = df_all["板块名称"].tolist()
    codes = df_all["板块代码"].tolist()
    cursor.execute(
        f"update stockBk set gnName='';"
    )
    sqlite3_conn.commit()
    for index in range(len(codes)):
        gn_name = names[index]
        cfg_df = None
        try:
            cfg_df = ak.stock_board_concept_cons_em(symbol=names[index])
        except Exception:
            cfg_df = ak.stock_board_industry_cons_em(symbol=names[index])
        stock_codes = cfg_df["代码"].tolist()
        for code in stock_codes:
            cursor.execute(f"select gnName from stockBk where code='{code}'")
            data = cursor.fetchone()
            if data is None or data[0] == "":
                gn_name_list = [gn_name]
                json_name = json.dumps(gn_name_list)
            else:
                old_gn_name = data[0]
                gn_names = json.loads(old_gn_name)
                gn_names.append(gn_name)
                gn_names = set(gn_names)
                gn_name_list = list(gn_names)
                json_name = json.dumps(gn_name_list)
            cursor.execute(
                f"update stockBk set gnName='{json_name}' where code='{code}';"
            )
            logger.warning(f"更新概念: {gn_name_list}, 股票：{code}")
            sqlite3_conn.commit()

    sqlite3_conn.close()


def task_update_history():
    """
    更新个股历史数据
    """
    df = update_data()
    code_list = df["代码"].tolist()

    date = datetime.now().date()
    while not is_workday(date) or date.weekday() in [5, 6]:
        date = date - timedelta(days=1)
    date = date - timedelta(days=1)
    date_num = convert_to_num(date)
    pre_date_num, _ = get_range_date(27)
    count = 1
    for code in code_list:
        stock_zh_a_hist_df = ak.stock_zh_a_hist(
            symbol=code,
            period="daily",
            start_date=pre_date_num,
            end_date=date_num,
            adjust="qfq",
            timeout=10,
        )
        del_cols = ["成交量", "成交额", "振幅", "涨跌幅", "涨跌额", "换手率", "日期", "开盘"]
        logger.info(f"正在更新：{code}")
        if stock_zh_a_hist_df.empty:
            continue
        stock_zh_a_hist_df.drop(del_cols, axis=1, inplace=True)
        df_json = stock_zh_a_hist_df.to_json()
        logger.info(count)
        r_con.set(code, df_json)
        count += 1